package org.lzh.controller;

import com.sun.org.apache.xpath.internal.operations.Mod;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.commons.io.FileUtils;
import org.lzh.pojo.Answer;
import org.lzh.pojo.Problem;
import org.lzh.pojo.User;
import org.lzh.service.*;
import org.lzh.util.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

//与学生有关的控制类
@Controller
@RequestMapping("student")
public class StudentController {
    @Autowired
    private UserService userService;

    @Autowired
    //用于教师添加用户
    private RegisterService registerService;

    @Autowired          //用于阅卷
    private AnswerService answerService;
    @Autowired
    private TestPaperAndProblemService testPaperAndProblemService;          //用于阅卷
//    ---------------------------------------------------------------单纯跳转操作-----------------------------------------------------------
    //添加学生用户的弹窗展示页面
    @RequestMapping(value="/showAddUser")
    public String showAddUser(){
        return "user/addUser";
    }



    //老师进入阅卷界面
    @RequestMapping(value="/marking")
    public String hhh(Model model,
                      String studentId){

            //根据该学生id查出做了哪张试卷
        Answer answer=answerService.findByStudentId(studentId);
        if(answer!=null){

                String testPaperId=answer.getTestPaperId();
                System.out.println(testPaperId);
                //根据试卷查出该试卷的所有题目和答案
                List<Problem> allProblem=testPaperAndProblemService.findAllProblem(testPaperId);

                model.addAttribute("studentList",allProblem);   //传问题和问题的答案

                model.addAttribute("answer",answer);        //传学生的答案


                User stu=userService.findById(studentId);
            System.out.println();
                model.addAttribute("score",stu.getScore());        //传分数


        }
        return "user/marking";

    }




        //尝试
        @RequestMapping(value = "/exportExcel")
        public ResponseEntity<byte[]> exportExcel(HttpServletRequest request,
                                                  @RequestHeader("User-Agent") String userAgent,
                                                  Model model)throws Exception {

            //所有学生列表
            List<User> list=userService.findAllStudent1();
            //导出变成wb
            XSSFWorkbook wb = userService.export(list);


            //新建一个文件保存excel，excel放的路径path
//            String path = request.getServletContext().getRealPath("/upload/");
            String path=ClassUtils.getDefaultClassLoader().getResource("static/upload").getPath();      //window就存在target的static的upload里，linux就存在/root的file:/root/jsptest-7.jar!/BOOT-INF/classes!/static/upload里
            System.out.println("------------------------------------------------"+path);
            String filename="学生成绩分班表.xlsx";

            //新建filename之前的目录path
            File filepath = new File(path,filename);
            // 判断路径是否存在，如果不存在就创建一个
            if (!filepath.getParentFile().exists()) {
                filepath.getParentFile().mkdirs();
            }
            File file = new File(path+File.separator+filename);


            //新建输出流把学生数据输出到path的路径上，输出到file的那个文件中
            FileOutputStream fos = new FileOutputStream(file);//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
            wb.write(fos);//将文档对象写入文件输出流
            fos.close();//关闭流



            System.out.println("导出到webapp的upload文件夹完成");



            // ok表示Http协议中的状态 200
            ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
            // 内容长度
            builder.contentLength(file.length());
            // application/octet-stream ： 二进制流数据（最常见的文件下载）。
            builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
            // 使用URLDecoder.decode对文件名进行解码
            filename = URLEncoder.encode(filename, "UTF-8");
            // 设置实际的响应文件名，告诉浏览器文件要用于【下载】、【保存】attachment 以附件形式
            // 不同的浏览器，处理方式不同，要根据浏览器版本进行区别判断
            if (userAgent.indexOf("MSIE") > 0) {
                // 如果是IE，只需要用UTF-8字符集进行URL编码即可
                builder.header("Content-Disposition", "attachment; filename=" + filename);
            } else {
                // 而FireFox、Chrome等浏览器，则需要说明编码的字符集
                // 注意filename后面有个*号，在UTF-8后面有两个单引号！
                builder.header("Content-Disposition", "attachment; filename*=UTF-8''" + filename);
            }
            return builder.body(FileUtils.readFileToByteArray(file));
        }



//    ---------------------------------------------------------------新增操作-----------------------------------------------------------


    //添加学生用户
    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public String login(HttpServletRequest request,
                        @ModelAttribute User user,//@ModelAttribute这个注解可以将注册时输入的值封装成user对象，很方便
                        Model model             //model可以用model.addAttribute 添加属性，然后在跳转的jsp页面里用，也很好用
    ) throws IOException {
        user.setStudentOrTeacher(0);
        if(!user.getId().isEmpty()&&!user.getUsername().isEmpty()&&!user.getPassword().isEmpty()&&!user.getImage().isEmpty()&&user.getStudentOrTeacher()!=null){

            System.out.println(user.getId()+user.getUsername()+user.getPassword()+user.getNote()+user.getImageLu()+user.getStudentOrTeacher());


            //判断是否已经有这个学号了
            if(registerService.findById(user.getId())!=null){
                model.addAttribute("id",user.getId());
                model.addAttribute("tip","学号已存在");
                return "user/addUser" ;
            }


            //中间这一串是处理注册时上传的图片image保存到 “当前绝对路径+/upload”
            // 上传文件路径
//            String path = request.getServletContext().getRealPath("/upload/");//获取Web项目的全路径
//            String path=ClassUtils.getDefaultClassLoader().getResource("static/upload").getPath();
//            System.out.println("------------------------------------------------"+path);
            String path= "/D:/项目上传的图片/img/";        //windows就存在d盘，linux就存在跟目录/的d盘
            System.out.println("------------------------------------------------path = "+path);

//            System.out.println(ResourceUtils.getURL("classpath:static").getPath() );
            System.out.println("path = " + path);
            // 上传文件名
            String filename = user.getImage().getOriginalFilename();
            File filepath = new File(path,filename);
            // 判断路径是否存在，如果不存在就创建一个
            if (!filepath.getParentFile().exists()) {
                filepath.getParentFile().mkdirs();
            }
            // 将上传文件保存到一个目标文件当中
            user.getImage().transferTo(new File(path+File.separator+ filename));//File.separator相当于斜杠



//            // 将用户添加到model
//            model.addAttribute("user", user);
            //将图片的地址（上传的文件名）赋值给ImageLu
            user.setImageLu(filename);
            registerService.register(user);
            System.out.println(user.getId()+user.getUsername()+user.getPassword()+user.getNote()+user.getImageLu());
            model.addAttribute("tip","添加成功");
            return "user/addUser";
        }
        model.addAttribute("username",user.getUsername());
        model.addAttribute("password",user.getPassword());
        model.addAttribute("tip","不能为空");
        return "user/addUser" ;
    }

//    ---------------------------------------------------------------删除操作-----------------------------------------------------------

    //删除一个用户
    @RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
    public @ResponseBody String deleteUser(@Param("id")Integer id) {
        int a= userService.deleteById(id);
        System.out.println(id);
        if(a > 0){
            return "OK";
        }else{
            return "FAIL";
        }
    }

    //根据ids批量删除用户
    @RequestMapping(value = "/batchDeleteUser", method = RequestMethod.POST)
    @ResponseBody
    public String batchdeleteById(@Param("ids")String ids){
        for(String id:ids.split(",")){
            Integer id1= Integer.valueOf(id);
            userService.deleteById(id1);
            System.out.println("-------------------------------------------------------数据库删除成功");
        }
//        model.addAttribute("tip", "删除成功");
        return "删除成功了";
    }


//    ---------------------------------------------------------------查询操作-----------------------------------------------------------
    //根据id查找用户,然后展示在更新操作的表上
    @RequestMapping(value = "/showUpdateUser")
    public String findById(@Param("id")String id,Model model){
        User user=userService.findById(id);
        model.addAttribute("user",user);
        return "user/updateUser";
    }

//    //通过用户名查询用户，之后跳转到显示页面上
//    @RequestMapping(value="/showSelectUser")
//    public String showSelectUser(String username,Model model){
//        User user1=userService.findByUsername(username);
//        if(user1==null){
//            model.addAttribute("wk","没有该用户");
//            return "forward:/login2";
//        }
//        model.addAttribute("user",user1);
//        System.out.println(user1);
//
//        return "user/selectUser";
//    }

    //查询出学生列表，然后跳转到用户管理页面  分页查询（通过数组）
    @RequestMapping(value="/student/{currPage}/{pageSize}")
    public String user(Model model,
                       @PathVariable("currPage") int currPage,
                       @PathVariable("pageSize") int pageSize,
                       @ModelAttribute User user){

            List<User> studentList1=userService.findByDynamic1(user);              //动态查询所有的数据,如果没有传user,则会查全部学生
            int length=studentList1.size();
            List<User> studentList =userService.findByDynamic(user,currPage,pageSize);         //把数据分页切割
            model.addAttribute("studentList",studentList);//分页后的学生数据
            model.addAttribute("length",length);//学生的全部数据的总条数
            int total=length/pageSize+(length%pageSize>0?1:0);            //总页数
            model.addAttribute("total",total);//学生的全部数据的总页数


        model.addAttribute("currPage",currPage);
        model.addAttribute("pageSize",pageSize);
//        model.addAttribute("tip","查询成功");
        model.addAttribute("user",user);

//查询出所有的答案中的学生id 实现答过题的才有阅卷按钮
        List<String> answerStudentIdList=answerService.findAllStudentId();
        model.addAttribute("answerStudentIdList",answerStudentIdList);

//        String path= ClassUtils.getDefaultClassLoader().getResource("static/upload").getPath();
//        System.out.println("------------------------------------------------"+path);
        return "user/user";
    }

    //分页查询（通过数组）
    @ResponseBody
    @RequestMapping("/array/{currPage}/{pageSize}")
    public List<User> getStudentByArray(@PathVariable("currPage") int currPage, @PathVariable("pageSize") int pageSize) {
        List<User> student = userService.findAllStudent(currPage, pageSize);
        return student;
}

    //动态查询学生用户
    @ResponseBody
    @RequestMapping("/find")
    public List<User> findByDynamic(@RequestBody User user){
        return userService.findByDynamic1(user);
    }


    //    ---------------------------------------------------------------更新操作-----------------------------------------------------------
    //根据id更新用户
    @RequestMapping(value = "/updateById")
    @ResponseBody   //用postman传json对象的数据一定要用@ResponseBody（返回）注解和对象的属性要用@RequestBody（接收）
    public int updateById(@RequestBody User user){return userService.updateById(user);}


    //老师修改学生个人信息
    @RequestMapping(value = "/updateUser",method = RequestMethod.POST)
    public String updateById(HttpServletRequest request,
                             @ModelAttribute User user,                          //@ModelAttribute这个注解可以将注册时输入的值封装成user对象，很方便
                             Model model    //model可以用model.addAttribute 添加属性，然后在跳转的jsp页面里用，也很好用
    ) throws Exception{
        System.out.println(user.getId()+user.getUsername()+user.getPassword()+user.getNote()+user.getImageLu());

        if(user.getPassword().isEmpty()){                   //如果密码为空就返回
            model.addAttribute("tip","密码不能为空");
            User user1=userService.findById(user.getId());
            model.addAttribute("user",user1);
            return "user/updateUser";
        }

        if(!user.getImage().isEmpty()){         //如果上传的图片不为空，就上传

            //中间这一串是处理注册时上传的图片image保存到 “当前绝对路径+/upload”
            // 上传文件路径
//            String path = request.getServletContext().getRealPath("/upload/");

//            String path= ClassUtils.getDefaultClassLoader().getResource("static/upload").getPath();
//            System.out.println("------------------------------------------------"+path);
            String path= "/D:/项目上传的图片/img/";        //windows就存在d盘，linux就存在跟目录/的d盘
            System.out.println("------------------------------------------------path = "+path);

            System.out.println(ResourceUtils.getURL("classpath:static").getPath() );
            System.out.println("path = " + path);
            // 上传文件名
            String filename = user.getImage().getOriginalFilename();
            File filepath = new File(path,filename);
            // 判断路径是否存在，如果不存在就创建一个
            if (!filepath.getParentFile().exists()) {
                filepath.getParentFile().mkdirs();
            }
            // 将上传文件保存到一个目标文件当中
            user.getImage().transferTo(new File(path+File.separator+ filename));

            //将图片的地址（上传的文件名）赋值给ImageLu
            user.setImageLu(filename);

        }else{  //如果没有上传图片就用以前的
            User user2=userService.findById(user.getId());
            user.setImageLu(user2.getImageLu());
        }
        System.out.println(user.getId()+user.getUsername()+user.getPassword()+user.getNote()+user.getImageLu());

        model.addAttribute("tip", "修改成功");
        userService.updateById(user);
//        User user1=userService.findById(user.getId());
        return "user/updateUser";
    }


    //老师批改试卷 更新成绩
    @RequestMapping(value = "/addScore", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
//    @ResponseBody
    public String addScore(
           /*@RequestBody*/  @ModelAttribute User user//@ModelAttribute这个注解可以将注册时输入的值封装成user对象，很方便
    ) throws IOException {

//更新操作 添加成绩

        //解决成绩重写时的逗号问题
        String b=user.getNote();
        b = b.replace(",","");
        user.setScore(Integer.valueOf(b));
        user.setNote("");


        int a= userService.updateByIdDynamic(user);
        System.out.println("-------------------------------------------"+a);
        System.out.println(user.getId()+user.getScore()+user.getStudentOrTeacher());

        return "redirect:/student/student/1/3";

    }





    //分班操作 更新分班
    @RequestMapping(value = "/classify")
//    @ResponseBody
    public String classify(
//           /*@RequestBody*/  @ModelAttribute User user,//@ModelAttribute这个注解可以将注册时输入的值封装成user对象，很方便
            Model model
    ) throws IOException {

        //先判断是否所有学生都做了试卷
        List<User> allStudentList =userService.findAllStudent1();       //查询所有学生
        List<String> allScoreNotNull =userService.findAllIdScoreNotNull();      //查找成绩不为空的学生id

        int c=0,b=0,a=0;            //abd班人数


        if(allScoreNotNull.size()==allStudentList.size()) {//若都做了才进行分班
            //学生总人数
            int studentTotal = allStudentList.size();
            //平均分成ABC三班
            int Average = studentTotal / 3;
            a = Average;
            b = Average;
            c = Average;
            //余数另外算
            if (studentTotal % 3 == 1) {
                c = c + 1;
            } else if (studentTotal % 3 == 2) {
                c = c + 1;
                b = b + 1;
            }
            model.addAttribute("A", a);         //a班人数
            model.addAttribute("B",b);         //b班人数
            model.addAttribute("C", c);         //c班人数


            //成绩进行排序且把学生放入班级里
            HashMap<String, Integer> map = new HashMap<>();
            LinkedList<Integer> list = new LinkedList<>();
            //把所有学生的id和分数放到map里
            for (int i = 0; i < allStudentList.size(); i++) {
                map.put(allStudentList.get(i).getId(), allStudentList.get(i).getScore());
            }
            //把所有学生的分数放到list里进行排序
            for (int i = 0; i < allStudentList.size(); i++) {
                list.add(allStudentList.get(i).getScore());
            }
            Collections.sort(list);
            System.out.println(list);
            System.out.println(map);


            for (int i = 0; i <list.size(); i++) {
                System.out.println(i);
                System.out.println(list.get(i));

                int score=list.get(i);

                // Map集合循环遍历方式三 推荐，尤其是容量大时
                 System.out.println("第三种：通过Map.entrySet遍历key和value");
                 for (Map.Entry<String,Integer> m : map.entrySet()) {
//                 System.out.println("key:" + m.getKey() + " value:" + m.getValue());

                     //如果c小于不等于0且值相同，id为k的学生就到c班，删除id为k的map，删除索引为i的list，c--
                     if(c>0&&score==m.getValue()){
                         System.out.println(list.get(0));
                         System.out.println(m.getKey()+"------------"+m.getValue());
                         System.out.println("------------------------c为"+c);
                         User user1=new User();
                         user1.setTeam("C");
                         user1.setStudentOrTeacher(0);
                         user1.setId(m.getKey());
                        int h= userService.updateByIdDynamic(user1);           //添加班级
                         //删除id为k的map
                         map.remove(m.getKey());
//                         list.remove(i);
                         System.out.println("+++++++++++++++++++++++"+h);
                         c--;
                         break;
                     }else if(b>0&&score==m.getValue()){  //如果b小于不等于0且值相同，id为k的学生就到b班，删除id为k的map，删除索引为i的list，b--
                         System.out.println(list.get(0));
                         System.out.println(m.getKey()+"------------"+m.getValue());
                         System.out.println("------------------------b为"+b);
                         User user1=new User();
                         user1.setTeam("B");
                         user1.setStudentOrTeacher(0);
                         user1.setId(m.getKey());
                         userService.updateByIdDynamic(user1);           //添加班级
                         //删除id为k的map
                         map.remove(m.getKey());
//                         list.remove(i);
                         b--;
                         break;
                     }else if(a>0&&score==m.getValue()){   //如果a小于不等于0且值相同，id为k的学生就到a班，删除id为k的map，删除索引为i的list，a--
                         System.out.println(list.get(0));
                         System.out.println(m.getKey()+"------------"+m.getValue());
                         System.out.println("------------------------a为"+a);
                         User user1=new User();
                         user1.setTeam("A");
                         user1.setStudentOrTeacher(0);
                         user1.setId(m.getKey());
                         userService.updateByIdDynamic(user1);           //添加班级
                         //删除id为k的map
                         map.remove(m.getKey());
//                         list.remove(i);
                         a--;
                         break;
                     }
                 }
            }

            model.addAttribute("studentTotal", studentTotal);         //总共多少名学生


        } else{ //若没做完就返回提示
            model.addAttribute("tip", "还有学生没有考试或你还没批改完试卷");

        }

        return "user/classify";

    }
}
